/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.servlet;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.springframework.lang.Nullable;

/**
 * Interface to be implemented by objects that define a mapping between
 * requests and handler objects.
 *
 * <p>This class can be implemented by application developers, although this is not
 * necessary, as {@link org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping}
 * and {@link org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping}
 * are included in the framework. The former is the default if no
 * HandlerMapping bean is registered in the application context.
 *
 * <p>HandlerMapping implementations can support mapped interceptors but do not
 * have to. A handler will always be wrapped in a {@link HandlerExecutionChain}
 * instance, optionally accompanied by some {@link HandlerInterceptor} instances.
 * The DispatcherServlet will first call each HandlerInterceptor's
 * {@code preHandle} method in the given order, finally invoking the handler
 * itself if all {@code preHandle} methods have returned {@code true}.
 *
 * <p>The ability to parameterize this mapping is a powerful and unusual
 * capability of this MVC framework. For example, it is possible to write
 * a custom mapping based on session state, cookie state or many other
 * variables. No other MVC framework seems to be equally flexible.
 *
 * <p>Note: Implementations can implement the {@link org.springframework.core.Ordered}
 * interface to be able to specify a sorting order and thus a priority for getting
 * applied by DispatcherServlet. Non-Ordered instances get treated as lowest priority.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see org.springframework.core.Ordered
 * @see org.springframework.web.servlet.handler.AbstractHandlerMapping
 * @see org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
 * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
 */

/**
 工作流程
	 DispatcherServlet 调用所有注册的 HandlerMapping beans的 getHandler() 方法
	 找到合适的处理器后，将其包装在 HandlerExecutionChain 中
	 按顺序调用所有 HandlerInterceptor 的 preHandle() 方法
	 如果所有拦截器都返回true，则调用实际的处理器
	 这些属性和方法共同构成了Spring MVC强大的请求映射机制，提供了高度灵活和可扩展的Web请求处理能力。

 结构层次分析
 顶层接口
	 HandlerMapping：最顶层的接口，定义了核心的请求处理映射功能。
	 MatchableHandlerMapping：扩展接口，提供额外的请求匹配能力。
 抽象基类
	 AbstractHandlerMapping：所有具体处理器映射的抽象基类，提供了通用的功能和配置。
	 AbstractHandlerMethodMapping<T>：专门用于方法级别的处理器映射，支持基于注解的请求映射。
	 AbstractUrlHandlerMapping：基于 URL 的处理器映射抽象类，支持 URL 模式匹配。
	 RequestMappingInfoHandlerMapping：基于 RequestMappingInfo 的处理器映射，是 @RequestMapping 注解的核心实现。
 具体实现类
	 RouterFunctionMapping：支持函数式编程风格的路由映射。
	 SimpleUrlHandlerMapping：简单的 URL 处理器映射，直接通过 URL 映射到处理器。
	 BeanNameUrlHandlerMapping：基于 Bean 名称的 URL 映射，将 Bean 名称作为 URL 路径。
	 WebSocketHandlerMapping：专门用于 WebSocket 连接的处理器映射。
	 SessionHandlerMapping：基于会话的处理器映射。
	 RequestMappingHandlerMapping：核心的请求映射处理器，处理 @RequestMapping 注解。
	 PathPatternMatchableHandlerMapping：支持路径模式匹配的处理器映射。
 设计原因
	 职责分离：通过分层设计，将不同类型的映射逻辑分离，每个类专注于特定的映射方式。
	 可扩展性：抽象基类提供了通用功能，具体实现类可以轻松扩展新的映射方式。
	 灵活性：支持多种映射策略，包括基于注解、URL、Bean 名称等。
	 性能优化：不同的映射方式可以根据需求选择最优的实现。
 各个类和接口的功能
 {@link HandlerMapping}：定义了基本的请求处理映射功能，如 getHandler(HttpServletRequest request)。
	{@link org.springframework.web.servlet.handler.MatchableHandlerMapping}：提供额外的请求匹配能力，允许外部组件查询请求匹配结果。
	{@link org.springframework.web.servlet.handler.AbstractHandlerMapping}：提供了通用的配置和初始化功能，如 setOrder(int order)。
	{@link org.springframework.web.servlet.handler.AbstractHandlerMethodMapping}<T>：支持基于方法的请求映射，处理 @RequestMapping 等注解。
	{@link org.springframework.web.servlet.handler.AbstractUrlHandlerMapping}：基于 URL 的映射，支持 URL 模式匹配。
	{@link org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping}：处理 RequestMappingInfo 对象，是 @RequestMapping 的核心实现。
	{@link org.springframework.web.servlet.function.support.RouterFunctionMapping}：支持函数式编程风格的路由映射。
	{@link org.springframework.web.servlet.handler.SimpleUrlHandlerMapping}：简单的 URL 映射，直接通过 URL 映射到处理器。
	{@link org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping}：基于 Bean 名称的 URL 映射。
	{@link WebSocketHandlerMapping}：专门用于 WebSocket 连接的处理器映射。
	{@link SessionHandlerMapping}：基于会话的处理器映射。
	{@link org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping}：核心的请求映射处理器，处理 @RequestMapping 注解。
	{@link org.springframework.web.servlet.handler.PathPatternMatchableHandlerMapping}：支持路径模式匹配的处理器映射。
 这种设计使得 Spring MVC 的请求映射机制既灵活又高效，能够适应各种复杂的应用场景。

 */
public interface HandlerMapping {

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains the mapped
	 * handler for the best matching pattern.
	 * @since 4.3.21
	 */
	/**
	 存储与最佳匹配模式对应的处理器对象的请求属性名称
	 用于在请求处理流程中保持处理器信息的一致性
	 */
	String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains the path
	 * used to look up the matching handler, which depending on the configured
	 * {@link org.springframework.web.util.UrlPathHelper} could be the full path
	 * or without the context path, decoded or not, etc.
	 * @since 5.2
	 * @deprecated as of 5.3 in favor of
	 * {@link org.springframework.web.util.UrlPathHelper#PATH_ATTRIBUTE} and
	 * {@link org.springframework.web.util.ServletRequestPathUtils#PATH_ATTRIBUTE}.
	 * To access the cached path used for request mapping, use
	 * {@link org.springframework.web.util.ServletRequestPathUtils#getCachedPathValue(ServletRequest)}.
	 */
	/**
	 用于查找匹配处理器的路径请求属性名称
	 从Spring 5.3开始已废弃，建议使用 UrlPathHelper.PATH_ATTRIBUTE 或 ServletRequestPathUtils.PATH_ATTRIBUTE
	 */
	@Deprecated
	String LOOKUP_PATH = HandlerMapping.class.getName() + ".lookupPath";

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains the path
	 * within the handler mapping, in case of a pattern match, or the full
	 * relevant URI (typically within the DispatcherServlet's mapping) else.
	 * <p>Note: This attribute is not required to be supported by all
	 * HandlerMapping implementations. URL-based HandlerMappings will
	 * typically support it, but handlers should not necessarily expect
	 * this request attribute to be present in all scenarios.
	 */
	/**
	 存储处理器映射内的路径请求属性名称
	 在模式匹配情况下存储匹配路径，在其他情况下存储完整的相关URI
	 */
	String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains the
	 * best matching pattern within the handler mapping.
	 * <p>Note: This attribute is not required to be supported by all
	 * HandlerMapping implementations. URL-based HandlerMappings will
	 * typically support it, but handlers should not necessarily expect
	 * this request attribute to be present in all scenarios.
	 */
	/**
	 存储最佳匹配模式的请求属性名称
	 用于URL-based HandlerMappings中存储匹配的模式字符串
	 */
	String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";

	/**
	 * Name of the boolean {@link HttpServletRequest} attribute that indicates
	 * whether type-level mappings should be inspected.
	 * <p>Note: This attribute is not required to be supported by all
	 * HandlerMapping implementations.
	 */
	/**
	 指示是否应检查类型级别映射的布尔属性名称
	 控制框架是否应该检查类级别的映射注解
	 */
	String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains the URI
	 * templates map, mapping variable names to values.
	 * <p>Note: This attribute is not required to be supported by all
	 * HandlerMapping implementations. URL-based HandlerMappings will
	 * typically support it, but handlers should not necessarily expect
	 * this request attribute to be present in all scenarios.
	 */
	/**
	 存储URI模板变量映射的请求属性名称
	 将变量名映射到实际值的Map
	 */
	String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains a map with
	 * URI variable names and a corresponding MultiValueMap of URI matrix
	 * variables for each.
	 * <p>Note: This attribute is not required to be supported by all
	 * HandlerMapping implementations and may also not be present depending on
	 * whether the HandlerMapping is configured to keep matrix variable content
	 */
	/**
	 存储URI矩阵变量的请求属性名称
	 包含每个URI变量名及其对应矩阵变量的MultiValueMap
	 */
	String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";

	/**
	 * Name of the {@link HttpServletRequest} attribute that contains the set of
	 * producible MediaTypes applicable to the mapped handler.
	 * <p>Note: This attribute is not required to be supported by all
	 * HandlerMapping implementations. Handlers should not necessarily expect
	 * this request attribute to be present in all scenarios.
	 */
	/**
	 存储可生产的媒体类型集合的请求属性名称
	 适用于映射处理器的可生产MediaType列表
	 */
	String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";


	/**
	 * Whether this {@code HandlerMapping} instance has been enabled to use parsed
	 * {@link org.springframework.web.util.pattern.PathPattern}s in which case
	 * the {@link DispatcherServlet} automatically
	 * {@link org.springframework.web.util.ServletRequestPathUtils#parseAndCache parses}
	 * the {@code RequestPath} to make it available for
	 * {@link org.springframework.web.util.ServletRequestPathUtils#getParsedRequestPath
	 * access} in {@code HandlerMapping}s, {@code HandlerInterceptor}s, and
	 * other components.
	 * @since 5.3
	 */
	/**
	 判断此HandlerMapping实例是否已启用解析的PathPatterns
	 默认返回false，表示使用传统的AntPathMatcher
	 从Spring 5.3开始支持PathPattern解析
	 */
	default boolean usesPathPatterns() {
		return false;
	}

	/**
	 * Return a handler and any interceptors for this request. The choice may be made
	 * on request URL, session state, or any factor the implementing class chooses.
	 * <p>The returned HandlerExecutionChain contains a handler Object, rather than
	 * even a tag interface, so that handlers are not constrained in any way.
	 * For example, a HandlerAdapter could be written to allow another framework's
	 * handler objects to be used.
	 * <p>Returns {@code null} if no match was found. This is not an error.
	 * The DispatcherServlet will query all registered HandlerMapping beans to find
	 * a match, and only decide there is an error if none can find a handler.
	 * @param request current HTTP request
	 * @return a HandlerExecutionChain instance containing handler object and
	 * any interceptors, or {@code null} if no mapping found
	 * @throws Exception if there is an internal error
	 */
	/**
	 核心方法，用于返回给定请求的处理器和拦截器
	 可基于请求URL、会话状态或任何其他因素进行选择
	 返回包含处理器对象和拦截器的 HandlerExecutionChain 实例
	 如果找不到匹配项则返回null（这不是错误）
	 */
	@Nullable
	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

}
